// 2D vector drawing xample, MHB 2013

#include "glfw.h"    // GL-Framework
#include "OpenGL.h" // My-Classes
#include <GL/gl.h>   // OpenGL
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <vector>

static double wwidth = 1024; // window size
static double wheight = 768;

using namespace std;

vector <Point*> points;
vector <Point> tmpPoints;

Point *clicked = new Point(-1, -1);
//Pascal *pasca;
int index = 0;
bool rightmouse = false;

// call this once to initialize OpenGL
void InitWindow(){  

	// init viewport to canvassize
    glViewport( 0, 0, wwidth, wheight);
    
	// projection matrix with clipping planes in three directions (same as window size and +- 1 in z)
	glMatrixMode( GL_PROJECTION);
    glLoadIdentity();
	glOrtho( 0, wwidth, 0, wheight, -1, 1);

	// modelview transform (identity)
	glMatrixMode( GL_MODELVIEW);
	glLoadIdentity();
}


// draw Polygon in (xpos, ypos)
void DrawPolygon(){
	glColor3f( 1.0, 0.0, 0.0); // drawing color

	glBegin( GL_LINE_STRIP);   // the following vertices will be drawn as line segments
	for(int i = 0; i < points.size(); i++){
		glVertex2f( points.at(i)->x, points.at(i)->y); // set vertex coordinates
	}
	glEnd();  // end of GL_LINE_STRIP
}


// this function is being called when a mouse button is pressed
void MouseCallback( int button, int press){
	int	x, y;
	if( button == 0 && press == 1){
		glfwGetMousePos( &x, &y);  // get mouse coordinates
		y = wheight - y;           // y goes upwards

		Point *p = new Point(x, y);
		points.push_back(p);
		//printf( "n=%5d  x=%5d  y=%5d\n", n, x, y);
		printf("x = %d, y = %d\n", p->x, p->y);

		// clear canvas and set background color
		glClearColor(0.8, 0.8, 0.8, 1.0);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		DrawPolygon();

		glFlush();     // make sure that everything is drawn and swap buffers
		glfwSwapBuffers();

		//pasca = new Pascal(points.size());
	}
	if( button == 1 && press == 1 ){
		rightmouse = true;
		clicked = new Point(-1, -1);
		glfwGetMousePos( &x, &y);  // get mouse coordinates
		y = wheight - y;           // y goes upwards
		Point *p = new Point(x, y);
		findPoint(p);

		if(clicked->y >= 0 && clicked->x >= 0){
			printf("Clicked x = %d, y = %d\n", clicked->x, clicked->y);
		}
	}
	if( button == 1 && press == 0 ){
		rightmouse = false;
	}
}

void findPoint(Point *mousePoint){
	int xdiff, ydiff, distanz, tmpDistanz;

	Point *tmpPoint = points.at(0);
	distanz = pow((double)tmpPoint->x - mousePoint->x, 2) + pow((double)tmpPoint->y - mousePoint->y, 2);

	for ( int i = 1; i < points.size(); i++ ){

		Point *tmp = points.at(i);
		tmpDistanz = pow((double)tmp->x - mousePoint->x, 2) + pow((double)tmp->y - mousePoint->y, 2);

		if(tmpDistanz < distanz && tmpDistanz < 400){
			clicked = tmp;
			index = i;
		}
	}
}

void MousePosCallback(int x, int y){
	y = wheight - y;  
	if(clicked->y >= 0 && clicked->x >= 0 && rightmouse){
		Point *p = new Point(x, y);
		points.at(index) = p;
		printf("newPoint: x: %d, y: %d\n", points.at(index)->x, points.at(index)->y);

		glClearColor(0.8, 0.8, 0.8, 1.0);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		DrawPolygon();

		glFlush();     // make sure that everything is drawn and swap buffers
		glfwSwapBuffers();
	}
}

void KeyCallback(int key, int push){
	if(push == 0 && key == 294){
		printf("Draw Bezier\n");
		double t = 0.5;
		//bezier(points, points.size());
	}
}

//void bezier(vector<Point*> thePoints, int n){

	/*vector<Point*> tmpFirst;
	double tmpBezier = 1.0;
	for(int i = 1; i < thePoints.size(); i++){
		Point *first0 = b0+b1;
		first0->x = first0->x * tmpBezier;
		first0->y = first0->y * tmpBezier;

		tmpBezier /= 2;
	}

	vector<Point*> tmpSecond;

	if(n <= 0){
		drawSpline();
		return;
	} else {
		bezier(tmpFirst, n - 1);
		bezier(tmpSecond, n - 1);
	}*/
//}

void drawSpline(){
	// mit tmpPoints
}

Point *operator+( Point a, Point b){ // Vergleich "greater"
	Point *result = new Point(a.x + b.x, a.y + b.y);
	return result;
}

Point *operator*( Point a, Point b){ // Vergleich "greater"
	Point *result = new Point(a.x * b.x, a.y * b.y);
	return result;
}

Point *operator*( double a, Point b){ // Vergleich "greater"
	Point *result = new Point(a * b.x, a * b.y);
	return result;
}

//======= MY CLASSES ========

Point::Point(int x, int y){
	this->x = x;
	this->y = y;
}

/*Pascal::Pascal(int n){
	for (int i = 0; i < n; i++){   
		
    }
}*/

// a simple example showing how to draw points using a mouse callback
int main () {

	printf("Here we go!\n");

	glfwInit();  // init GLFW and open an OpenGL Window
	glfwOpenWindow( wwidth, wheight, 8, 8, 8, 8, 24, 0, GLFW_WINDOW);

	// initialize drawing with OpenGL
	InitWindow();

	// here we say that on press-event the above function "MouseCallback" will be called
	glfwSetMouseButtonCallback( &MouseCallback);
	glfwSetMousePosCallback(&MousePosCallback);
	glfwSetKeyCallback(&KeyCallback);
	
	// endless loop until window is closed
	while(true) {
		
		glfwWaitEvents( ); // do nothing until user presses mouse button
		
		if(!glfwGetWindowParam(GLFW_OPENED)) {
			break;
		}
	}
	
	glfwTerminate();  // thats all, Folks
	printf("Good Bye!\n");

	return 0;
}

